xen: Get rid of some VCPUF_* flags and move into their own byte fields.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 29 Mar 2007 15:52:40 +0000 (16:52 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 29 Mar 2007 15:52:40 +0000 (16:52 +0100)
Signed-off-by: Keir Fraser <keir@xensource.com>
30 files changed:
xen/arch/ia64/vmx/vlsapic.c
xen/arch/ia64/vmx/vmmu.c
xen/arch/ia64/xen/domain.c
xen/arch/ia64/xen/hypercall.c
xen/arch/ia64/xen/vhpt.c
xen/arch/powerpc/domain.c
xen/arch/powerpc/domain_build.c
xen/arch/x86/domain.c
xen/arch/x86/domain_build.c
xen/arch/x86/domctl.c
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/vlapic.c
xen/arch/x86/i387.c
xen/arch/x86/mm.c
xen/arch/x86/mm/hap/hap.c
xen/arch/x86/mm/shadow/multi.c
xen/arch/x86/traps.c
xen/common/compat/domain.c
xen/common/domain.c
xen/common/domctl.c
xen/common/event_channel.c
xen/common/keyhandler.c
xen/common/sched_credit.c
xen/common/sched_sedf.c
xen/common/schedule.c
xen/include/asm-ia64/event.h
xen/include/asm-powerpc/event.h
xen/include/asm-x86/event.h
xen/include/asm-x86/i387.h
xen/include/xen/sched.h

index a6d0a64c8a8065934cab15e594b7c81e5a8da393..e64a08f6a8d203b8b86e784dc21a6a70aa7b3dd7 100644 (file)
@@ -692,7 +692,7 @@ static void vlsapic_write_ipi(VCPU *vcpu, uint64_t addr, uint64_t value)
     if (targ == NULL)
         panic_domain(NULL, "Unknown IPI cpu\n");
 
-    if (!test_bit(_VCPUF_initialised, &targ->vcpu_flags) ||
+    if (!targ->is_initialised ||
         test_bit(_VCPUF_down, &targ->vcpu_flags)) {
 
         struct pt_regs *targ_regs = vcpu_regs(targ);
@@ -717,7 +717,7 @@ static void vlsapic_write_ipi(VCPU *vcpu, uint64_t addr, uint64_t value)
             printk("arch_boot_vcpu: huh, already awake!");
         }
     } else {
-        int running = test_bit(_VCPUF_running, &targ->vcpu_flags);
+        int running = targ->is_running;
         vlsapic_deliver_ipi(targ, ((ipi_d_t)value).dm, 
                             ((ipi_d_t)value).vector);
         vcpu_unblock(targ);
index ee456c030e8cdf25e9369ec88f59aa0ac6eb9fa5..b7ea24dd46dada7ef6f24cf46bca91d66213f81b 100644 (file)
@@ -598,7 +598,7 @@ IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu, u64 va, u64 ps)
     vcpu_get_rr(vcpu, va, &args.rid);
     args.ps = ps;
     for_each_vcpu (d, v) {
-        if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+        if (!v->is_initialised)
             continue;
 
         args.vcpu = v;
index 9520373825c7c326049ce7531d1fdd6ed2f519b6..d7d3e67aa641c14d8ce527d1dc7f28f9541d5d67 100644 (file)
@@ -657,7 +657,7 @@ int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
                v->arch.iva = er->iva;
        }
 
-       if (test_bit(_VCPUF_initialised, &v->vcpu_flags))
+       if (v->is_initialised)
                return 0;
 
        if (d->arch.is_vti) {
@@ -676,10 +676,12 @@ int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
        /* This overrides some registers. */
        vcpu_init_regs(v);
 
-       /* Don't redo final setup. Auto-online VCPU0. */
-       if (!test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) &&
-           (v->vcpu_id == 0))
-               clear_bit(_VCPUF_down, &v->vcpu_flags);
+       if (!v->is_initialised) {
+               v->is_initialised = 1;
+               /* Auto-online VCPU0 when it is initialised. */
+               if (v->vcpu_id == 0)
+                       clear_bit(_VCPUF_down, &v->vcpu_flags);
+       }
 
        return 0;
 }
@@ -1067,7 +1069,7 @@ int construct_dom0(struct domain *d,
        /* Sanity! */
        BUG_ON(d != dom0);
        BUG_ON(d->vcpu[0] == NULL);
-       BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
+       BUG_ON(v->is_initialised);
 
        printk("*** LOADING DOMAIN 0 ***\n");
 
@@ -1188,7 +1190,7 @@ int construct_dom0(struct domain *d,
 
        printk("Dom0: 0x%lx\n", (u64)dom0);
 
-       set_bit(_VCPUF_initialised, &v->vcpu_flags);
+       v->is_initialised = 1;
        clear_bit(_VCPUF_down, &v->vcpu_flags);
 
        /* Build firmware.
index 98a3165d0642f2d546ff0fba7c8fe526f85198e3..d3630ded83c8166f11415ca8c1e710eba870ccb1 100644 (file)
@@ -81,11 +81,11 @@ fw_hypercall_ipi (struct pt_regs *regs)
                return;
 
        if (vector == XEN_SAL_BOOT_RENDEZ_VEC
-           && (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)
+           && (!targ->is_initialised
                || test_bit(_VCPUF_down, &targ->vcpu_flags))) {
 
                /* First start: initialize vpcu.  */
-               if (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)) {
+               if (!targ->is_initialised) {
                        struct vcpu_guest_context c;
                
                        memset (&c, 0, sizeof (c));
@@ -112,9 +112,7 @@ fw_hypercall_ipi (struct pt_regs *regs)
                        printk ("arch_boot_vcpu: huu, already awaken!\n");
        }
        else {
-               int running = test_bit(_VCPUF_running,
-                                      &targ->vcpu_flags);
-               
+               int running = targ->is_running;
                vcpu_pend_interrupt(targ, vector);
                vcpu_unblock(targ);
                if (running)
index bbb5d6f751a301316b0456ae1de05e719f343275..07d1810ee8a7a97e1d70d6180c3929334e7360f5 100644 (file)
@@ -184,7 +184,7 @@ domain_purge_swtc_entries(struct domain *d)
 {
        struct vcpu* v;
        for_each_vcpu(d, v) {
-               if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+               if (!v->is_initialised)
                        continue;
 
                /* Purge TC entries.
@@ -202,7 +202,7 @@ domain_purge_swtc_entries_vcpu_dirty_mask(struct domain* d,
 
        for_each_vcpu_mask(vcpu, vcpu_dirty_mask) {
                struct vcpu* v = d->vcpu[vcpu];
-               if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+               if (!v->is_initialised)
                        continue;
 
                /* Purge TC entries.
@@ -263,7 +263,7 @@ void domain_flush_vtlb_all(struct domain* d)
        struct vcpu *v;
 
        for_each_vcpu(d, v) {
-               if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+               if (!v->is_initialised)
                        continue;
 
                if (v->processor == cpu)
@@ -341,7 +341,7 @@ void domain_flush_vtlb_range (struct domain *d, u64 vadr, u64 addr_range)
        smp_mb();
 
        for_each_vcpu (d, v) {
-               if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+               if (!v->is_initialised)
                        continue;
 
                if (HAS_PERVCPU_VHPT(d)) {
@@ -407,7 +407,7 @@ __domain_flush_vtlb_track_entry(struct domain* d,
        if (HAS_PERVCPU_VHPT(d)) {
                for_each_vcpu_mask(vcpu, entry->vcpu_dirty_mask) {
                        v = d->vcpu[vcpu];
-                       if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+                       if (!v->is_initialised)
                                continue;
 
                        /* Invalidate VHPT entries.  */
index 1ecf35a666adbf34cd35d90240a240f511f97405..e8e3c7805fc4c11e5a302f870888652e21d0b623 100644 (file)
@@ -168,10 +168,13 @@ int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
     d->shared_info->wc_nsec = dom0->shared_info->wc_nsec;
     d->shared_info->arch.boot_timebase = dom0->shared_info->arch.boot_timebase;
 
-    /* Auto-online VCPU0 when it is initialised. */
-    if ( !test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) &&
-         (v->vcpu_id == 0) )
-        clear_bit(_VCPUF_down, &v->vcpu_flags);
+    if ( !v->is_initialised )
+    {
+        v->is_initialised = 1;
+        /* Auto-online VCPU0 when it is initialised. */
+        if ( v->vcpu_id == 0 )
+            clear_bit(_VCPUF_down, &v->vcpu_flags);
+    }
 
     cpu_init_vcpu(v);
 
index af7ad3db4516e309795011230de10140db810ffa..e8ee2b01dd670bd15788dcc3beb4bb3893499c00 100644 (file)
@@ -273,7 +273,7 @@ int construct_dom0(struct domain *d,
 
     ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr);
 
-    set_bit(_VCPUF_initialised, &v->vcpu_flags);
+    v->is_initialised = 1;
     clear_bit(_VCPUF_down, &v->vcpu_flags);
 
     rc = 0;
index 005813306c1a3e4e8a523f340868d7aac7c3bd1c..8da2287a757b7edfe879c6eff254cf44ad0cd5e9 100644 (file)
@@ -563,9 +563,7 @@ int arch_set_info_guest(
 #endif
     }
 
-    clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
-    if ( flags & VGCF_I387_VALID )
-        set_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
+    v->fpu_initialised = !!(flags & VGCF_I387_VALID);
 
     v->arch.flags &= ~TF_kernel_mode;
     if ( (flags & VGCF_in_kernel) || is_hvm_vcpu(v)/*???*/ )
@@ -600,7 +598,7 @@ int arch_set_info_guest(
         hvm_load_cpu_guest_regs(v, &v->arch.guest_context.user_regs);
     }
 
-    if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+    if ( v->is_initialised )
         goto out;
 
     memset(v->arch.guest_context.debugreg, 0,
@@ -699,7 +697,7 @@ int arch_set_info_guest(
         update_domain_wallclock_time(d);
 
     /* Don't redo final setup */
-    set_bit(_VCPUF_initialised, &v->vcpu_flags);
+    v->is_initialised = 1;
 
     if ( paging_mode_enabled(d) )
         paging_update_paging_modes(v);
index a05060ee5e58ef6d35b28a7b995c5b275bd7300d..6cecf6b56f2cee2066737ce410328e07362ab209 100644 (file)
@@ -254,7 +254,7 @@ int construct_dom0(struct domain *d,
     /* Sanity! */
     BUG_ON(d->domain_id != 0);
     BUG_ON(d->vcpu[0] == NULL);
-    BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
+    BUG_ON(v->is_initialised);
 
     printk("*** LOADING DOMAIN 0 ***\n");
 
@@ -901,7 +901,7 @@ int construct_dom0(struct domain *d,
 
     update_domain_wallclock_time(d);
 
-    set_bit(_VCPUF_initialised, &v->vcpu_flags);
+    v->is_initialised = 1;
     clear_bit(_VCPUF_down, &v->vcpu_flags);
 
     /*
index 503b0000c7b22773ae31e08bcf24d80ed77da117..9cf3825cd1d53f23f92d5ed6f05e31552ccc8d74 100644 (file)
@@ -448,7 +448,7 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
 #endif
 
     c(flags &= ~(VGCF_i387_valid|VGCF_in_kernel));
-    if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) )
+    if ( v->fpu_initialised )
         c(flags |= VGCF_i387_valid);
     if ( !test_bit(_VCPUF_down, &v->vcpu_flags) )
         c(flags |= VGCF_online);
index 2c783bfe7a53e07454265ae61ec2c6b712de8367..632e993fc1f33a78b25aa32840b6f84885c34055 100644 (file)
@@ -85,7 +85,7 @@ void hvm_disable(void)
 void hvm_stts(struct vcpu *v)
 {
     /* FPU state already dirty? Then no need to setup_fpu() lazily. */
-    if ( !test_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags) )
+    if ( !v->fpu_dirtied )
         hvm_funcs.stts(v);
 }
 
@@ -332,10 +332,10 @@ void hvm_vcpu_reset(struct vcpu *v)
     hvm_funcs.vcpu_initialise(v);
 
     set_bit(_VCPUF_down, &v->vcpu_flags);
-    clear_bit(_VCPUF_initialised, &v->vcpu_flags);
-    clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
-    clear_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags);
     clear_bit(_VCPUF_blocked, &v->vcpu_flags);
+    v->fpu_initialised = 0;
+    v->fpu_dirtied     = 0;
+    v->is_initialised  = 0;
 
     vcpu_unpause(v);
 }
@@ -722,7 +722,7 @@ int hvm_bringup_ap(int vcpuid, int trampoline_vector)
 
     LOCK_BIGLOCK(d);
     rc = -EEXIST;
-    if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+    if ( !v->is_initialised )
         rc = boot_vcpu(d, vcpuid, ctxt);
     UNLOCK_BIGLOCK(d);
 
index af2d0bbe448f4aec6e5c64070371c9815fa2b611..e80ec083b282c494d63f0f5b8820f7db13aadb4c 100644 (file)
@@ -303,7 +303,7 @@ static int vlapic_accept_irq(struct vcpu *v, int delivery_mode,
         if ( trig_mode && !(level & APIC_INT_ASSERT) )
             break;
         /* FIXME How to check the situation after vcpu reset? */
-        if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+        if ( v->is_initialised )
             hvm_vcpu_reset(v);
         v->arch.hvm_vcpu.init_sipi_sipi_state =
             HVM_VCPU_INIT_SIPI_SIPI_STATE_WAIT_SIPI;
@@ -318,7 +318,7 @@ static int vlapic_accept_irq(struct vcpu *v, int delivery_mode,
         v->arch.hvm_vcpu.init_sipi_sipi_state =
             HVM_VCPU_INIT_SIPI_SIPI_STATE_NORM;
 
-        if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+        if ( v->is_initialised )
         {
             gdprintk(XENLOG_ERR, "SIPI for initialized vcpu %x\n", v->vcpu_id);
             goto exit_and_crash;
index 899f80da3b272fbdc053fdfdfe81208356f3efd8..f376a677545bb2df8c93ba62ccacf15c917dc565 100644 (file)
@@ -21,7 +21,7 @@ void init_fpu(void)
     __asm__ __volatile__ ( "fninit" );
     if ( cpu_has_xmm )
         load_mxcsr(0x1f80);
-    set_bit(_VCPUF_fpu_initialised, &current->vcpu_flags);
+    current->fpu_initialised = 1;
 }
 
 void save_init_fpu(struct vcpu *v)
@@ -76,7 +76,7 @@ void save_init_fpu(struct vcpu *v)
             : "=m" (*fpu_ctxt) );
     }
 
-    clear_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags);
+    v->fpu_dirtied = 0;
     write_cr0(cr0|X86_CR0_TS);
 }
 
index d6ca78726ae3d235d64552869d68df38ddfa923f..b559b1f567a5ee76e664e3800dad861364c4f996 100644 (file)
@@ -1089,7 +1089,7 @@ static int alloc_l3_table(struct page_info *page)
      */
     if ( (pfn >= 0x100000) &&
          unlikely(!VM_ASSIST(d, VMASST_TYPE_pae_extended_cr3)) &&
-         d->vcpu[0] && test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) )
+         d->vcpu[0] && d->vcpu[0]->is_initialised )
     {
         MEM_LOG("PAE pgd must be below 4GB (0x%lx >= 0x100000)", pfn);
         return 0;
index 47139f2627cff04b76723ab3a033634d9ab4e57f..ac4df6ec7065ea6f010edce4592fcd02d0f4f3fa 100644 (file)
@@ -569,7 +569,8 @@ void hap_update_cr3(struct vcpu *v, int do_locking)
 
     HERE_I_AM;
     /* Don't do anything on an uninitialised vcpu */
-    if ( !is_hvm_domain(d) && !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) {
+    if ( !is_hvm_domain(d) && !v->is_initialised )
+    {
         ASSERT(v->arch.cr3 == 0);
         return;
     }
index 7945913429785428658ddf4088f3752598e79184..b1419a7b27d07a112fdd5c2e45d480e972b13aad 100644 (file)
@@ -3427,7 +3427,7 @@ sh_update_cr3(struct vcpu *v, int do_locking)
 #endif
 
     /* Don't do anything on an uninitialised vcpu */
-    if ( !is_hvm_domain(d) && !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+    if ( !is_hvm_domain(d) && !v->is_initialised )
     {
         ASSERT(v->arch.cr3 == 0);
         return;
index c19cc491e6bc9cece067d0bdba00a245b7225392..67e8ca0b6d03d01bf7e72eab51308781c23c7235 100644 (file)
@@ -1030,7 +1030,7 @@ long do_fpu_taskswitch(int set)
     else
     {
         v->arch.guest_context.ctrlreg[0] &= ~X86_CR0_TS;
-        if ( test_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags) )
+        if ( v->fpu_dirtied )
             clts();
     }
 
index 12929122f668d8f0d05038079d4434636cb73a6d..a7f2d8ff435bc408ca70486da96c5083924a9cb5 100644 (file)
@@ -44,7 +44,7 @@ int compat_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg)
 
         LOCK_BIGLOCK(d);
         rc = -EEXIST;
-        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+        if ( !v->is_initialised )
             rc = boot_vcpu(d, vcpuid, cmp_ctxt);
         UNLOCK_BIGLOCK(d);
 
index f9e43a04ceda3eababb0171056fdb282dd2ba187..1b3e68bd0e5c7f7fd69c9c54841cff1c14a43fa0 100644 (file)
@@ -484,7 +484,7 @@ int boot_vcpu(struct domain *d, int vcpuid, vcpu_guest_context_u ctxt)
 {
     struct vcpu *v = d->vcpu[vcpuid];
 
-    BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
+    BUG_ON(v->is_initialised);
 
     return arch_set_info_guest(v, ctxt);
 }
@@ -503,13 +503,13 @@ int vcpu_reset(struct vcpu *v)
 
     set_bit(_VCPUF_down, &v->vcpu_flags);
 
-    clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
-    clear_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags);
+    v->fpu_initialised = 0;
+    v->fpu_dirtied     = 0;
+    v->is_polling      = 0;
+    v->is_initialised  = 0;
     clear_bit(_VCPUF_blocked, &v->vcpu_flags);
-    clear_bit(_VCPUF_initialised, &v->vcpu_flags);
     clear_bit(_VCPUF_nmi_pending, &v->vcpu_flags);
     clear_bit(_VCPUF_nmi_masked, &v->vcpu_flags);
-    clear_bit(_VCPUF_polling, &v->vcpu_flags);
 
  out:
     UNLOCK_BIGLOCK(v->domain);
@@ -546,7 +546,7 @@ long do_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg)
 
         LOCK_BIGLOCK(d);
         rc = -EEXIST;
-        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+        if ( !v->is_initialised )
             rc = boot_vcpu(d, vcpuid, ctxt);
         UNLOCK_BIGLOCK(d);
 
@@ -554,7 +554,7 @@ long do_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg)
         break;
 
     case VCPUOP_up:
-        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+        if ( !v->is_initialised )
             return -EINVAL;
 
         if ( test_and_clear_bit(_VCPUF_down, &v->vcpu_flags) )
index 0f0c5998da6c104fe5c256b98ab3b1e117b0a8e3..5d7e5d7f90bd86271bf289a5f93ca2b1a30c8254 100644 (file)
@@ -105,7 +105,7 @@ void getdomaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info)
         {
             if ( !(v->vcpu_flags & VCPUF_blocked) )
                 flags &= ~XEN_DOMINF_blocked;
-            if ( v->vcpu_flags & VCPUF_running )
+            if ( v->is_running )
                 flags |= XEN_DOMINF_running;
             info->nr_online_vcpus++;
         }
@@ -517,7 +517,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
             goto getvcpucontext_out;
 
         ret = -ENODATA;
-        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+        if ( !v->is_initialised )
             goto getvcpucontext_out;
 
 #ifdef CONFIG_COMPAT
@@ -576,7 +576,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
 
         op->u.getvcpuinfo.online   = !test_bit(_VCPUF_down, &v->vcpu_flags);
         op->u.getvcpuinfo.blocked  = test_bit(_VCPUF_blocked, &v->vcpu_flags);
-        op->u.getvcpuinfo.running  = test_bit(_VCPUF_running, &v->vcpu_flags);
+        op->u.getvcpuinfo.running  = v->is_running;
         op->u.getvcpuinfo.cpu_time = runstate.time[RUNSTATE_running];
         op->u.getvcpuinfo.cpu      = v->processor;
         ret = 0;
index 783dfb99f1db7add88c1cc5df44af7c22fe12204..0db68de41a8004510f302059c8f0d140a0058128 100644 (file)
@@ -529,11 +529,17 @@ void evtchn_set_pending(struct vcpu *v, int port)
     }
     
     /* Check if some VCPU might be polling for this event. */
-    if ( unlikely(d->is_polling) && likely(xchg(&d->is_polling, 0)) )
+    if ( unlikely(d->is_polling) )
     {
+        d->is_polling = 0;
+        smp_mb(); /* check vcpu poll-flags /after/ clearing domain poll-flag */
         for_each_vcpu ( d, v )
-            if ( test_and_clear_bit(_VCPUF_polling, &v->vcpu_flags) )
-                vcpu_unblock(v);
+        {
+            if ( !v->is_polling )
+                continue;
+            v->is_polling = 0;
+            vcpu_unblock(v);
+        }
     }
 }
 
index e3eb0b9cee3d0a845445d9c08801573577bd6cec..838c1222a496cb17992b70802865dbebdf6b23ac 100644 (file)
@@ -188,7 +188,7 @@ static void dump_domains(unsigned char key)
             printk("    VCPU%d: CPU%d [has=%c] flags=%lx "
                    "upcall_pend = %02x, upcall_mask = %02x ",
                    v->vcpu_id, v->processor,
-                   test_bit(_VCPUF_running, &v->vcpu_flags) ? 'T':'F',
+                   v->is_running ? 'T':'F',
                    v->vcpu_flags,
                    vcpu_info(v, evtchn_upcall_pending),
                    vcpu_info(v, evtchn_upcall_mask));
index 6bbbb7ae5b9eb73c9200ebd2d88f58fe2dc3a4b1..6bc79cf0a4d86593869508437711cd6ecb6699c2 100644 (file)
@@ -411,8 +411,7 @@ __csched_vcpu_is_migrateable(struct vcpu *vc, int dest_cpu)
      * Don't pick up work that's in the peer's scheduling tail. Also only pick
      * up work that's allowed to run on our CPU.
      */
-    return !test_bit(_VCPUF_running, &vc->vcpu_flags) &&
-           cpu_isset(dest_cpu, vc->cpu_affinity);
+    return !vc->is_running && cpu_isset(dest_cpu, vc->cpu_affinity);
 }
 
 static int
index 8f79dd23b498922da9a173163a1d93fcf3dd7503..8a1223a03b0f6ebc5fb36904cc2901f50f40b1e4 100644 (file)
@@ -1189,7 +1189,7 @@ void sedf_wake(struct vcpu *d)
 static void sedf_dump_domain(struct vcpu *d)
 {
     printk("%i.%i has=%c ", d->domain->domain_id, d->vcpu_id,
-           test_bit(_VCPUF_running, &d->vcpu_flags) ? 'T':'F');
+           d->is_running ? 'T':'F');
     printk("p=%"PRIu64" sl=%"PRIu64" ddl=%"PRIu64" w=%hu"
            " sc=%i xtr(%s)=%"PRIu64" ew=%hu",
            EDOM_INFO(d)->period, EDOM_INFO(d)->slice, EDOM_INFO(d)->deadl_abs,
index 6fc968126e64f71bf46994c0acb6d508747d8e1a..93c15d151a3051eb9652592404488992238c8400 100644 (file)
@@ -123,7 +123,7 @@ int sched_init_vcpu(struct vcpu *v, unsigned int processor)
     {
         per_cpu(schedule_data, v->processor).curr = v;
         per_cpu(schedule_data, v->processor).idle = v;
-        set_bit(_VCPUF_running, &v->vcpu_flags);
+        v->is_running = 1;
     }
 
     TRACE_2D(TRC_SCHED_DOM_ADD, v->domain->domain_id, v->vcpu_id);
@@ -172,7 +172,7 @@ void vcpu_sleep_sync(struct vcpu *v)
 {
     vcpu_sleep_nosync(v);
 
-    while ( !vcpu_runnable(v) && test_bit(_VCPUF_running, &v->vcpu_flags) )
+    while ( !vcpu_runnable(v) && v->is_running )
         cpu_relax();
 
     sync_vcpu_execstate(v);
@@ -208,7 +208,12 @@ static void vcpu_migrate(struct vcpu *v)
 
     vcpu_schedule_lock_irqsave(v, flags);
 
-    if ( test_bit(_VCPUF_running, &v->vcpu_flags) ||
+    /*
+     * NB. Check of v->running happens /after/ setting migration flag
+     * because they both happen in (different) spinlock regions, and those
+     * regions are strictly serialised.
+     */
+    if ( v->is_running ||
          !test_and_clear_bit(_VCPUF_migrating, &v->vcpu_flags) )
     {
         vcpu_schedule_unlock_irqrestore(v, flags);
@@ -234,7 +239,7 @@ static void vcpu_migrate(struct vcpu *v)
 void vcpu_force_reschedule(struct vcpu *v)
 {
     vcpu_schedule_lock_irq(v);
-    if ( test_bit(_VCPUF_running, &v->vcpu_flags) )
+    if ( v->is_running )
         set_bit(_VCPUF_migrating, &v->vcpu_flags);
     vcpu_schedule_unlock_irq(v);
 
@@ -310,14 +315,13 @@ static long do_poll(struct sched_poll *sched_poll)
     if ( !guest_handle_okay(sched_poll->ports, sched_poll->nr_ports) )
         return -EFAULT;
 
-    /* These operations must occur in order. */
     set_bit(_VCPUF_blocked, &v->vcpu_flags);
-    set_bit(_VCPUF_polling, &v->vcpu_flags);
-    smp_wmb();
+    v->is_polling = 1;
     d->is_polling = 1;
-    smp_wmb();
 
     /* Check for events /after/ setting flags: avoids wakeup waiting race. */
+    smp_wmb();
+
     for ( i = 0; i < sched_poll->nr_ports; i++ )
     {
         rc = -EFAULT;
@@ -342,7 +346,7 @@ static long do_poll(struct sched_poll *sched_poll)
     return 0;
 
  out:
-    clear_bit(_VCPUF_polling, &v->vcpu_flags);
+    v->is_polling = 0;
     clear_bit(_VCPUF_blocked, &v->vcpu_flags);
     return rc;
 }
@@ -651,8 +655,8 @@ static void schedule(void)
     ASSERT(next->runstate.state != RUNSTATE_running);
     vcpu_runstate_change(next, RUNSTATE_running, now);
 
-    ASSERT(!test_bit(_VCPUF_running, &next->vcpu_flags));
-    set_bit(_VCPUF_running, &next->vcpu_flags);
+    ASSERT(!next->is_running);
+    next->is_running = 1;
 
     spin_unlock_irq(&sd->schedule_lock);
 
@@ -673,7 +677,13 @@ static void schedule(void)
 
 void context_saved(struct vcpu *prev)
 {
-    clear_bit(_VCPUF_running, &prev->vcpu_flags);
+    /* Clear running flag /after/ writing context to memory. */
+    smp_wmb();
+
+    prev->is_running = 0;
+
+    /* Check for migration request /after/ clearing running flag. */
+    smp_mb();
 
     if ( unlikely(test_bit(_VCPUF_migrating, &prev->vcpu_flags)) )
         vcpu_migrate(prev);
@@ -704,8 +714,12 @@ static void vcpu_singleshot_timer_fn(void *data)
 static void poll_timer_fn(void *data)
 {
     struct vcpu *v = data;
-    if ( test_and_clear_bit(_VCPUF_polling, &v->vcpu_flags) )
-        vcpu_unblock(v);
+
+    if ( !v->is_polling )
+        return;
+
+    v->is_polling = 0;
+    vcpu_unblock(v);
 }
 
 /* Initialise the data structures. */
index c3d67cfa2c6639cf6368ee6d8bc7fe0872ec6271..92cdddac794a0a54c6dd9b184eb12ade1bd6cf5d 100644 (file)
@@ -20,10 +20,10 @@ static inline void vcpu_kick(struct vcpu *v)
      * locks) but the key insight is that each change will cause
      * evtchn_upcall_pending to be polled.
      * 
-     * NB2. We save VCPUF_running across the unblock to avoid a needless
+     * NB2. We save the running flag across the unblock to avoid a needless
      * IPI for domains that we IPI'd to unblock.
      */
-    int running = test_bit(_VCPUF_running, &v->vcpu_flags);
+    int running = v->is_running;
     vcpu_unblock(v);
     if ( running )
         smp_send_event_check_cpu(v->processor);
index 1dd4e5b3c3d7392a0a9b05473cdb6fc8f2e29360..9f10ee98baf32b4a5a08ac5ff890e505e9f4ff52 100644 (file)
@@ -27,7 +27,7 @@
 static inline void evtchn_notify(struct vcpu *v)
 {
 #ifdef XXX_NO_SMP_YET
-    int running = test_bit(_VCPUF_running, &v->vcpu_flags);
+    int running = v->is_running;
     vcpu_unblock(v);
     if (running)
         smp_send_event_check_cpu(v->processor);
@@ -73,10 +73,10 @@ static inline void vcpu_kick(struct vcpu *v)
      * locks) but the key insight is that each change will cause
      * evtchn_upcall_pending to be polled.
      *
-     * NB2. We save VCPUF_running across the unblock to avoid a needless
+     * NB2. We save the running flag across the unblock to avoid a needless
      * IPI for domains that we IPI'd to unblock.
      */
-    int running = test_bit(_VCPUF_running, &v->vcpu_flags);
+    int running = v->is_running;
     vcpu_unblock(v);
     if (running)
         smp_send_event_check_cpu(v->processor);
index 86f6653f834203adad3f538b2929e6c15575f05c..922ede6fc61f7aa31d6dd741556dc9648decad2c 100644 (file)
@@ -20,10 +20,10 @@ static inline void vcpu_kick(struct vcpu *v)
      * locks) but the key insight is that each change will cause
      * evtchn_upcall_pending to be polled.
      * 
-     * NB2. We save VCPUF_running across the unblock to avoid a needless
+     * NB2. We save the running flag across the unblock to avoid a needless
      * IPI for domains that we IPI'd to unblock.
      */
-    int running = test_bit(_VCPUF_running, &v->vcpu_flags);
+    int running = v->is_running;
     vcpu_unblock(v);
     if ( running )
         smp_send_event_check_cpu(v->processor);
index a324af013ff5405a1a8547f16a465ffdfde4f489..b0ce77aac39e58d52fadc945a05f8cf8009364ba 100644 (file)
@@ -18,9 +18,9 @@ extern void init_fpu(void);
 extern void save_init_fpu(struct vcpu *v);
 extern void restore_fpu(struct vcpu *v);
 
-#define unlazy_fpu(v) do {                                      \
-    if ( test_bit(_VCPUF_fpu_dirtied, &(v)->vcpu_flags) )       \
-        save_init_fpu(v);                                       \
+#define unlazy_fpu(v) do {                      \
+    if ( (v)->fpu_dirtied )                     \
+        save_init_fpu(v);                       \
 } while ( 0 )
 
 #define load_mxcsr(val) do {                                    \
@@ -33,9 +33,10 @@ static inline void setup_fpu(struct vcpu *v)
     /* Avoid recursion. */
     clts();
 
-    if ( !test_and_set_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags) )
+    if ( !v->fpu_dirtied )
     {
-        if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) )
+        v->fpu_dirtied = 1;
+        if ( v->fpu_initialised )
             restore_fpu(v);
         else
             init_fpu();
index 2a86f778060974e8a26ac8ee5f437e8dbd8dcf78..7a1257ee99980a7764217df51e097db1d4fd0f3a 100644 (file)
@@ -100,6 +100,17 @@ struct vcpu
     } runstate_guest; /* guest address */
 #endif
 
+    /* Has the FPU been initialised? */
+    bool_t           fpu_initialised;
+    /* Has the FPU been used since it was last saved? */
+    bool_t           fpu_dirtied;
+    /* Is this VCPU polling any event channels (SCHEDOP_poll)? */
+    bool_t           is_polling;
+    /* Initialization completed for this VCPU? */
+    bool_t           is_initialised;
+    /* Currently running on a CPU? */
+    bool_t           is_running;
+
     unsigned long    vcpu_flags;
 
     spinlock_t       pause_lock;
@@ -423,41 +434,26 @@ extern struct domain *domain_list;
 /*
  * Per-VCPU flags (vcpu_flags).
  */
- /* Has the FPU been initialised? */
-#define _VCPUF_fpu_initialised 0
-#define VCPUF_fpu_initialised  (1UL<<_VCPUF_fpu_initialised)
- /* Has the FPU been used since it was last saved? */
-#define _VCPUF_fpu_dirtied     1
-#define VCPUF_fpu_dirtied      (1UL<<_VCPUF_fpu_dirtied)
  /* Domain is blocked waiting for an event. */
-#define _VCPUF_blocked         2
+#define _VCPUF_blocked         0
 #define VCPUF_blocked          (1UL<<_VCPUF_blocked)
- /* Currently running on a CPU? */
-#define _VCPUF_running         3
-#define VCPUF_running          (1UL<<_VCPUF_running)
- /* Initialization completed. */
-#define _VCPUF_initialised     4
-#define VCPUF_initialised      (1UL<<_VCPUF_initialised)
  /* VCPU is offline. */
-#define _VCPUF_down            5
+#define _VCPUF_down            1
 #define VCPUF_down             (1UL<<_VCPUF_down)
  /* NMI callback pending for this VCPU? */
-#define _VCPUF_nmi_pending     8
+#define _VCPUF_nmi_pending     2
 #define VCPUF_nmi_pending      (1UL<<_VCPUF_nmi_pending)
  /* Avoid NMI reentry by allowing NMIs to be masked for short periods. */
-#define _VCPUF_nmi_masked      9
+#define _VCPUF_nmi_masked      3
 #define VCPUF_nmi_masked       (1UL<<_VCPUF_nmi_masked)
- /* VCPU is polling a set of event channels (SCHEDOP_poll). */
-#define _VCPUF_polling         10
-#define VCPUF_polling          (1UL<<_VCPUF_polling)
  /* VCPU is paused by the hypervisor? */
-#define _VCPUF_paused          11
+#define _VCPUF_paused          4
 #define VCPUF_paused           (1UL<<_VCPUF_paused)
  /* VCPU is blocked awaiting an event to be consumed by Xen. */
-#define _VCPUF_blocked_in_xen  12
+#define _VCPUF_blocked_in_xen  5
 #define VCPUF_blocked_in_xen   (1UL<<_VCPUF_blocked_in_xen)
  /* VCPU affinity has changed: migrating to a new CPU. */
-#define _VCPUF_migrating       13
+#define _VCPUF_migrating       6
 #define VCPUF_migrating        (1UL<<_VCPUF_migrating)
 
 static inline int vcpu_runnable(struct vcpu *v)